/*
 * AppServResponseHandler.cpp
 *
 *  Created on: Apr 9, 2017
 *      Author: zhangjf
 */

#include <Poco/Timer.h>
#include <Poco/JSON/Parser.h>
#include <Poco/JSON/Object.h>
#include <Poco/Dynamic/Var.h>

using namespace Poco;
using namespace Poco::JSON;
using namespace Poco::Dynamic;

#include "Packet.h"
#include "PacketReceiver.h"
#include "MainApplication.h"
#include "WebSocketNotificationnHandler.h"

using namespace util;

void WebSocketNotificationnHandler::run()
{
    char buffer[1024];
    int flags;
    int n;
    Parser parser;

    Timer timer(10 * 60 * 1000);
	TimerCallback<WebSocketNotificationnHandler> tc(*this, &WebSocketNotificationnHandler::onTimer);

    do
    {
    	try
        {
    		parser.reset();
    		n = _webSocket.receiveFrame(buffer, sizeof(buffer), flags);
			poco_information(*pLogger, Poco::format("Frame received (length=%d, flags=0x%x)", n, unsigned(flags)));
			buffer[n] = 0;
			poco_information(*pLogger, buffer);

			std::string strPacket(buffer, n);
			poco_information(*pLogger, strPacket);
			Object::Ptr joPacket = parser.parse(strPacket).extract<Object::Ptr>();
			if (joPacket->has("jsonrpc") && joPacket->has("method"))
			{
				std::string strJsonrpc = joPacket->getValue<std::string>("jsonrpc");
				std::string strMethod = joPacket->getValue<std::string>("method");
				std::string strSid = joPacket->getObject("params")->getValue<std::string>("sid");

				std::string strResp;
				if (strMethod == "Login")
				{
					poco_information(*pLogger, std::string("send frame: ") + strPacket);
					handleLoginRequest(strSid, strResp);
					_webSocket.sendFrame(strResp.c_str(), strResp.length(), flags);
				    timer.start(tc);
				}
				else if (strMethod == "Logout")
				{
					handleLogoutRequest(strSid, strResp);
					poco_information(*pLogger, std::string("send frame: ") + strResp);
					_webSocket.sendFrame(strResp.c_str(), strResp.length(), flags);
				}
				else if (strMethod == "NotifySID")
				{
					poco_information(*pLogger, buffer);
					//_webSocket.sendFrame(buffer, n, flags);
				}
				else
				{
					PacketHeader head;
					head.type = MSG_TYPE::MSG_TYPE_JSONRPC;
					head.length = n;

					poco_information(*pLogger, "send to appserv: " + strPacket);
					_streamSocket.sendBytes(&head, sizeof(head));
					_streamSocket.sendBytes(buffer, n);
				}
			}
        }
    	catch(Exception& exc)
    	{
    		poco_information(*pLogger, "exception: " + exc.displayText());
    	}
    } while (n > 0 && (flags & WebSocket::FRAME_OP_BITMASK) != WebSocket::FRAME_OP_CLOSE);

    poco_information(*pLogger, "WebSocket connection closed.");
}

void WebSocketNotificationnHandler::onTimer(Timer& timer)
{
	//TODO:: wss timeout ...
}

void WebSocketNotificationnHandler::handleLoginRequest(std::string& strSid, std::string& strResp)
{
//	Parser parser;
//	Object::Ptr joReq = parser.parse(strResp).extract<Object::Ptr>();
//
//	Object joParams = joReq.
//	std::string strSid = joReq->getValue("")

	Object joResp;
	joResp.set("jsonrpc", "2.0");

	Object joRst;
	joRst.set("method", "Login");
	joRst.set("result", "success");

	joResp.set("result", joRst);

	strResp = ((DynamicStruct)joResp).toString();
}

void WebSocketNotificationnHandler::handleLogoutRequest(std::string& strReq, std::string& strResp)
{
	Object joResp;
	joResp.set("jsonrpc", "2.0");

	Object joRst;
	joRst.set("method", "Logout");
	joRst.set("result", "success");

	joResp.set("result", joRst);

	strResp = ((DynamicStruct)joResp).toString();
}
